package main

import (
	"context"
	"fmt"
	"github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
	"github.com/micro/go-micro/v2"
	"github.com/micro/go-micro/v2/registry"
	"go-gin-api/app/config"
	"go-gin-api/app/controller/tag"
	"go-gin-api/app/middleware/cors"
	"go-gin-api/app/middleware/exception"
	"go-gin-api/app/middleware/jaeger"
	"go-gin-api/app/middleware/logger"
	grpctag "go-gin-api/app/proto/tag"
	"log"
	"net/http"
	"os"
	"os/signal"
	"time"
)

func main() {
	gin.SetMode(config.AppMode)
	engine := gin.New()
	// 性能分析 - 正式环境不要使用！！！
	pprof.Register(engine)
	// 设置路由
	engine.Use(cors.Next()) //允许跨域，如果nginx已经开启跨域，请注释该行
	//设置路由中间件
	engine.Use(logger.SetUp(), exception.SetUp(), jaeger.SetUp())
	// 使用etcd注册
	//micReg := etcd.NewRegistry(registryOptions)
	// 新建服务
	service := micro.NewService(
		micro.Name("web-tag"),
		//micro.Registry(micReg),
		micro.Version("latest"),
	)
	// 服务初始化
	service.Init()
	// tag
	tagRouter := engine.Group("/tag")
	{
		//调用 gRPC 服务
		tagClient := grpctag.NewTagService("tag", service.Client())
		tagController := tag.NewTag(tagClient)
		tagRouter.POST("", tagController.Add)
		tagRouter.PUT("/:id", tagController.Edit)
		tagRouter.DELETE("/:id", tagController.Delete)
		tagRouter.GET("", tagController.List)
		tagRouter.GET("/:id", tagController.Info)
	}
	server := &http.Server{
		Addr         : config.AppPort,
		Handler      : engine,
		ReadTimeout  : config.AppReadTimeout * time.Second,
		WriteTimeout : config.AppWriteTimeout * time.Second,
	}
	go func() {
		if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
			log.Fatalf("HTTP server listen: %s\n", err)
		}
	}()
	// 等待中断信号以优雅地关闭服务器（设置 5 秒的超时时间）
	signalChan := make(chan os.Signal)
	signal.Notify(signalChan, os.Interrupt)
	sig := <-signalChan
	log.Println("Get Signal:", sig)
	log.Println("Shutdown Server ...")

	ctx, cancel := context.WithTimeout(context.Background(), 5 * time.Second)
	defer cancel()
	if err := server.Shutdown(ctx); err != nil {
		log.Fatal("Server Shutdown:", err)
	}
	log.Println("Server exiting")
}

// 注册etcd
func registryOptions(ops *registry.Options) {
	ops.Addrs = []string{fmt.Sprintf("%s:%d", config.EtcdHostTag, config.EtcdPortTag)}
}
